package Mapas;

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import java.util.LinkedList;

/**
 * @author Alvaro Garcia Tapia
 * @author Pablo Mosquera Diaz
 * @author Victor Navarro Ortego
 * @author Adrian Neila Serrano
 * @author Daniel Sanchez Suarez
 * 
 * @proyecto Gestor de Tareas Online
 * @version 1.61
 */
public class LienzoParaArrastrarFiguras extends Canvas implements
		MouseMotionListener {

	/**
	 * Lista de figuras a dibujar.
	 */
	private LinkedList<InterfaceFigura> listaFiguras = new LinkedList<InterfaceFigura>();

	/**
	 * Si actualmente se est� arrastrando o no el rect�ngulo.
	 */
	private InterfaceFigura figuraArrastrandose = null;

	/**
	 * Si actualmente se est� arrastrando o no el rect�ngulo.
	 */
	private InterfaceFigura figuraEnPos = null;

	/**
	 * x en la que estaba anteriormente el rat�n.
	 */
	private int xAnteriorRaton;

	/**
	 * y en la que estaba anteriormente el rat�n
	 */
	private int yAnteriorRaton;
	
	/**
	 * ancho que han de tener las figuras
	 */
	private int ancho;
        
        /**
	 * retardo de actualización del canvas
	 */
        private int retardo = 0;

	/**
	 * Crea un nuevo objeto ArrastrarGrafico.
	 */
	public LienzoParaArrastrarFiguras(int ancho) {
		this.ancho = ancho;
		addMouseMotionListener(this);
	}

	/**
	 * A�ada una figura a la lista de figuras a dibujar
	 * 
	 * @param figura
	 *            Una nueva figura a dibujar
	 */
	public void addFigura(InterfaceFigura figura) {
		listaFiguras.add(figura);
	}

	/**
	 * Quita la figura en la lista de figuras a dibujar.
	 * 
	 * @param figura
	 *            figura a quitar de la lista.
	 */
	public void removeFigura(InterfaceFigura figura) {
		listaFiguras.remove(figura);
	}

	/**
	 * Para darle un tama�o por defecto al Canvas de dibujo
	 * 
	 * @return Dimension por defecto.
	 */
	@Override
	public Dimension getPreferredSize() {
		return new Dimension(500, 500);
	}

	/**
	 * Dibuja el rect�ngulo en la posici�n indicada por por xRectangulo e
	 * yRectangulo.
	 * 
	 * @param g
	 *            Graphics con el que dibujar.
	 */
	@Override
	public void paint(Graphics g) {
		for (InterfaceFigura figura : listaFiguras) {
			figura.dibujate(g);
		}
	}

	/**
	 * M�todo al que se llama cuando se arrastra el rat�n. Se comprueba con el
	 * atributo arrastrando si est� empezando el arrastre o ya se esta en medio
	 * del mismo. Si se comienza el arrastre, se guardan las coordenadas del
	 * rat�n que vienen en el evento MouseEvent y se cambia el valor del
	 * atributo arrastrando. Si se est� en medio de un arrastre, se calcula la
	 * nueva posici�n del rect�ngulo y se llama al m�todo repaint() para que se
	 * pinte.
	 * 
	 * @param e
	 *            Evento del rat�n
	 */
	public void mouseDragged(MouseEvent e) {
		// Si comienza el arrastre ...
		if (figuraArrastrandose == null) {
			// Se guardan las posiciones del rat�n
			xAnteriorRaton = e.getX();
			yAnteriorRaton = e.getY();
			// y se marca que ha comenzado el arrastre.
			figuraArrastrandose = dameFigura(e);
		} else {	
                    if(retardo == 8){
                        retardo = 0;
    
				// Si ya hab�a empezado el arrastre, se calculan las nuevas
				// coordenadas del rect�ngulo
			int x = figuraArrastrandose.getX();
                        
			if(figuraArrastrandose.getX()/ancho<e.getX()/ancho)
				x = figuraArrastrandose.getX()+(int)(Math.abs(figuraArrastrandose.getX()-e.getX())/ancho)*ancho;
			else if(figuraArrastrandose.getX()>e.getX())
				x = figuraArrastrandose.getX()-(int)(Math.abs(figuraArrastrandose.getX()-e.getX())/ancho+1)*ancho;
			
			if(x<0) 
				x=0;
			else if (x+((Rectangulo)figuraArrastrandose).getAncho()>this.getSize().getWidth())
				x=this.getWidth()-((Rectangulo)figuraArrastrandose).getAncho();
			
			int y = e.getY();
			
			if(y<0) 
				y=0;
			else if (y+((Rectangulo)figuraArrastrandose).getAlto()>this.getSize().getHeight())
				y=this.getHeight()-((Rectangulo)figuraArrastrandose).getAlto();
			
			figuraEnPos = dameFigura2(x,y);
				
			if(figuraEnPos == null)
				figuraArrastrandose.setPosicion(x,y);
			else{
				if((y<figuraEnPos.getY()+((Rectangulo)figuraEnPos).getAlto()/2) &&
						(y>figuraEnPos.getY()))
						y = figuraEnPos.getY()-((Rectangulo)figuraArrastrandose).getAlto();
				else
						y = figuraEnPos.getY()+((Rectangulo)figuraEnPos).getAlto();

				
				if(y<0) 
					y=0;
				else if (y+((Rectangulo)figuraArrastrandose).getAlto()>this.getSize().getHeight())
					y=this.getHeight()-((Rectangulo)figuraArrastrandose).getAlto();

				figuraArrastrandose.setPosicion(x,y);
			}


				// Se guarda la posici�n del rat�n para el siguiente c�lculo
				xAnteriorRaton = e.getX();
				yAnteriorRaton = e.getY();
			// y se manda repintar el Canvas
			repaint();
                    }
                    else
                        retardo++;
                    }
	}

	/**
	 * Para ver si el rat�n est� dentro del rect�ngulo. Si est� dentro, puede
	 * comenzar el arrastre.
	 * 
	 * @param e
	 *            El evento de rat�n
	 * 
	 * @return true si el rat�n est� dentro del rect�ngulo
	 */
	public InterfaceFigura dameFigura(MouseEvent e) {
		for (InterfaceFigura figura : listaFiguras) {
			if (figura.estaDentro(e.getX(), e.getY())) {
				return figura;
			}
		}

		return null;
	}

	public InterfaceFigura dameFigura2(int x,int y) {
		for (InterfaceFigura figura : listaFiguras) {
			if (figura.estaDentro(x, y)) {
				return figura;
			}
		}

		return null;
	}

	/**
	 * El rat�n se mueve sin arrastrar. Se marca fin de arrastre.
	 * 
	 * @param e
	 *            E
	 */
	public void mouseMoved(MouseEvent e) {
		figuraArrastrandose = null;
	}
}
